class QueueOfInt{
    private queue : number[] = []

    public Push(value : number): void{
        this.queue.push(value)
    }

    public Pop() :number| undefined{
        return this.queue.shift()
    }
}

const intQueue :QueueOfInt = new QueueOfInt();
intQueue.Push(10)
intQueue.Push(35)

console.log(intQueue.Pop())
console.log(intQueue.Pop())

class Queue<T>{
    private queue :T[] = []

    public Push(value:T):void{
        this.queue.push(value)
    }

    public Pop():T|undefined{
        return this.queue.shift()
    }
}

console.log("calling generic queue");
const queue :Queue<number> = new Queue<number>();

queue.Push(10)
queue.Push(34)
console.log(queue.Pop())
console.log(queue.Pop())


// add   contrained-generics demo
interface IStream{
    ReadStream():Int8Array;
}

class Data<T extends IStream>{

    ReadStream(stream : T){
        let output = stream.ReadStream();
        console.log(output.byteLength)
    }
}

class WebStream implements IStream{
    ReadStream():Int8Array{
        let array :Int8Array = new Int8Array(8);
        for(let index : number = 0; index < array.length;index++){
            array[index] = index + 3
        }
        return array;
    }
}
class DiskStream implements IStream{
    ReadStream():Int8Array{
        let array :Int8Array = new Int8Array(20);
        for(let index : number = 0; index < array.length;index++){
            array[index] = index + 5;
        }
        return array;
    }
}

const  webStream = new Data<WebStream>();
const diskStream = new Data<DiskStream>();

webStream.ReadStream(new WebStream());
diskStream.ReadStream(new DiskStream());

